package org.scheduler4j;

import java.util.Date;

import org.scheduler4j.util.DateUtil;

public class Month extends DayDuration {
	/**
	 * the year this month belongs to
	 */
	private int year;
	/**
	 * the month number.
	 */
	private int month;

	/**
	 * constructor with start day and the start date of the week.
	 * 
	 * @param day
	 * @param weekStartDay
	 */
	public Month(int year, int month) {
		setYearAndMonth(year, month);
		setStartDate(new Day(DateUtil.firstDayOfMonth(year, month)));
		setEndDate(new Day(DateUtil.lastDayOfMonth(year, month)));
	}

	/**
	 * constructor with start day, the start date of the week should be Sunday.
	 * 
	 * @param date
	 */
	public Month(Date date) {
		this(DateUtil.getYear(date), DateUtil.getMonth(date));
	}

	/**
	 * constructor with start date.
	 * 
	 * @param day
	 */
	public Month(Day day) {
		this(day.getYear(), day.getMonth());
	}

	/**
	 * get the next month.
	 * @return
	 */
	public Month nextMonth() {
		return new Month(getEndDate().tomorrow());
	}

	/**
	 * get the previous month.
	 * @return
	 */
	public Month previousMonth() {
		return new Month(getStartDate().yesterday());
	}

	/**
	 * get amont of days in a month.
	 * @return
	 */
	public int daysInMonth() {
		return (month == 1 || month == 3 || month == 5 || month == 7
				|| month == 8 || month == 10 || month == 12) ? 31
				: (month != 2 ? 30 : (getYearObject().isLeapYear() ? 29 : 28));
	}

	public int getYear() {
		return year;
	}

	public Year getYearObject() {
		return new Year(year);
	}

	public int getMonth() {
		return month;
	}

	private void setYearAndMonth(int year, int month) {
		this.year = year;
		if (month <= 0 || month > 12) {
			throw new InvalidMonthException();
		}
		this.month = month;
	}

	@Override
	public int hashCode() {
		return year * 12 + month;
	}

	@Override
	public String toString() {
		return "[" + year + "-" + month + "]";
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == null || !(obj instanceof Month)) {
			return false;
		}
		Month tmp = (Month) obj;
		return tmp.year == year && tmp.month == month;
	}

}
